const hasAdjacent = (x, y, arr, p = 1) => [[1, 0], [1, 1], [0, 1], [-1, 0], [-1, 1], [-1, -1], [0, -1], [1, -1]].some(a => arr[x + a[0]] !== undefined && arr[x + a[0]][y + a[1]] === p),
    doWork = (a, f) => a.map((a, x) => a.map((b, y) => f(x, y, b))),
    outerEdgesOf = z => doWork(z, (x, y, a) => hasAdjacent(x, y, z) && a !== 1 ? 1 : 0),
    innerEdgesOf = z => doWork(z, (x, y, a) => a === 1 && hasAdjacent(x, y, z, 0) ? 1 : 0),
    grow = z => doWork(z, (x, y, a) => (a === 0 && hasAdjacent(x, y, z)) || a === 1 ? 1 : a),
    shrink = z => doWork(z, (x, y, a) => a === 1 && hasAdjacent(x, y, z, 0) ? 0 : a);